let rows = [];
let currentRows;
let now;
let nowO;
let time;

let duration = 1200;
let dformat = d3.format(",");

let colorS = ["#c7474e", "#4d7a83", "#40367b", "#4c4c87", "#606f97", "#629ab3"]
// id0、id1、id2、id3、id4、id5
let width = 900,
	height = 500,
	margin = { left: 30, right: 80, top: 0, bottom: 20 };
let maskD = 30,
	maskP = 630;

// 数据预处理
const series = (data) => {
	data = d3.nest()
		.key(d => d.name)
		.entries(data);
	data.y = "sensor";
	return data;
};

// d3元素配置
const line = d3.line()
	.defined(d => !isNaN(d.value))
	.x(d => x(d.date))
	.y(d => y(d.value))
	.curve(d3.curveBasis);

const x = d3.scaleTime().range([margin.left*2, width-margin.right*2])
const y = d3.scaleLinear().range([height-margin.bottom, margin.top]);
const z = d3.scaleOrdinal(d3.schemeCategory10)
const zc = d3.scaleOrdinal(colorS)
const t = d3.transition().duration(duration).ease(d3.easeLinear)
const dateMax = data => d3.max(data, d => d3.max(d.values, d => d.date))
const dateMin = data => d3.min(data, d => d3.min(d.values, d => d.date))

const xAxis = g => g
	.attr("transform", `translate(0, ${height-margin.bottom})`)
	.call(d3.axisBottom(x)
		.ticks(3)   
		.tickFormat(d3.timeFormat("%Y-%m-%d %H:%M:%S"))
		.tickSizeOuter(0));

const yAxis = g => g
	.attr("class", "axisY")
	.attr("transform", `translate(${margin.left * 2}, 0)`)
	.call(d3.axisLeft(y).ticks(2).tickFormat(d3.format(".0s"))) 

const svg = d3.select("svg#chart");

const gX = svg.append("g"),
	gY = svg.append("g"),
	gZ = svg.append("g");

const update = (data, data2) => {
	let maxY = d3.max(data2, d => d3.max(d.values, d => d.value))

	x.domain([dateMin(data), dateMax(data)])
	y.domain([0, maxY])

	let transX = x(data[1].values[0].date) - x(data[1].values[1].date);

	gX.transition().duration(duration).ease(d3.easeLinear).call(xAxis);
	gY.transition().duration(duration).ease(d3.easeLinear).call(yAxis);

	d3.selectAll(".lines")
		.data(data)
		.transition()
		.duration(duration)
		.ease(d3.easeLinear)
		.attr("transform", `translate( ${transX} )`)
		.attr("d", d => line(d.values))

	Label.data(data)
		.datum(d => ({ key: d.key, value: d.values[d.values.length - 2].value, date: d.values[d.values.length - 2].date }))
		.transition()
		.duration(duration)
		.ease(d3.easeLinear)
		.attr("style", d => `left: ${x(d.date) - maskD}px; top: ${y(d.value) - maskD / 2}px; background-color: ${zc(d.key)}`)

	LabelsText2.data(data)
		.datum(d => ({value: d.values[d.values.length - 2].value}))
		.transition()
		.duration(duration)
		.text(d => dformat( d.value));
}

var getSay = function() {
	axios({
		method: "get",
		url: "/say",
		responseType: "text",
		timeout: 1000
	}).then((function(t) {
		console.log(t.data.payload)
	})).catch((function() {}))
}

var getInfo = function() {
	axios({
		method: "get",
		url: "/info",
		responseType: "json",
		timeout: 1000
	}).then((function(r) {
		now = moment(r.data.t, "YYYY/MM/DD HH:mm:ss")
		array = r.data.d.map(d => ({name: d.n, date: moment(r.data.t, "YYYY-MM-DD HH:mm:ss"), value: d.v}));
		for (var a in array) rows.push(array[a]);
	})).catch((function() {}))
}

let config = 0;

d3.interval(() => {
	getInfo();
	if (rows.length < 15)
	{
		return;
	}

	if (config == 0)
	{
		config = 1;
		rows = rows.map(d => ({date: moment(d.date, "YYYY/MM/DD HH:mm:ss"), 
			name: d.name,
			value: d.value}))

		currentRows = rows;

		let currentData = series(rows.filter((d) => { return d.date <= now }));
		let data = currentData;

		time = dateMin(data)
		x.domain([time, dateMax(data)])
		y.domain([0, d3.max(data, d => d3.max(d.values, d => d.value))])
		z.domain(data.map(d => d.name));
		zc.domain(data.map(d => d.name));

		gX.call(xAxis);
		gY.call(yAxis);

		gZ.append("defs").append("clipPath")
			.attr("id", "clip")
			.append("rect")
			.attr("width", maskP)
			.attr("height", height - margin.top)
			.attr("transform", `translate( ${margin.left *2 }, 20)`)

		let Series = gZ.append("g")
			.attr("class", "type")
			.attr("font-size", "12")
			.attr("fill", "none")
			.attr("clip-path", "url(#clip)")  

		Lines = Series.selectAll("g.type")
			.data(data)
			.enter()
			.append("path")
			.attr("d", d => line(d.values))

		Lines.attr("class", d => `lines ${d.key}`)
			.attr("stroke", d => zc(d.key))

		Labels = d3.select("#labels")
			.selectAll("labels")
			.data(data)

		Label = Labels.enter().append("div")
			.attr("class", "labels label")
			.datum(d => ({ key: d.key, value: d.values[d.values.length - 1].value, date: d.values[d.values.length - 1].date }))
			.attr("style", d => `left: ${x(d.date) - maskD}px; top: ${y(d.value) - maskD/2}px; background-color: ${zc(d.key)}`)

		LabelsText = Label.append("text")
			.attr("class", "labels labelsText")
			.text(d => d.key)

		LabelsText2 = Label.append("text")
			.attr("class", "labels labelsText2")
			.text(d => d.value)
	}

	currentRows = rows.filter((d) => { return d.date <= now });
	console.log("now", now.format("YYYY/MM/DD HH:mm:ss"))
	currentData = series(currentRows);

	delta_now = now.subtract(1, 'seconds');
	currentRowsO = rows.filter((d) => { return d.date <= delta_now });
	currentDataO = series(currentRowsO);

	update(currentDataO, currentData);

	d3.select(".time").text(now.format("YYYY/MM/DD HH:mm:ss"));

	if (rows.length > 5*30) {
		rows.shift();
		rows.shift();
		rows.shift();
		rows.shift();
		rows.shift();
	}
}, 800)
